package com.googlecode.auctionx.mercadolivre;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;

import com.googlecode.auctionx.AuctionXException;
import com.googlecode.auctionx.Restriction;
import com.googlecode.auctionx.Search;
import com.googlecode.auctionx.beans.Auction;
import com.googlecode.auctionx.beans.Features;
import com.googlecode.auctionx.beans.Feedback;
import com.googlecode.auctionx.mercadolivre.xml.SimpleXMLParser;
import com.googlecode.auctionx.mercadolivre.xml.elements.Item;
import com.googlecode.auctionx.mercadolivre.xml.elements.Response;

public class MercadoLivre {
	private String searchUrl = "http://www.mercadolivre.com.br/jm/searchXml";
	
	private String getXML(String u) {
        URL url;
		try {
			url = new URL(u);
			URLConnection conn = url.openConnection();
	        conn.setDoOutput(true);
	        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        String line;
	        StringBuilder resultado = new StringBuilder();
	        while ((line = rd.readLine()) != null) {
	            resultado.append(line);
	            resultado.append("\n");
	        }
	        rd.close();
	        return resultado.toString();
		} catch (MalformedURLException e) {
			throw new AuctionXException(e);
		} catch (IOException e) {
			throw new AuctionXException(e);
		}		
	}

	private String createQueryString(Collection<Restriction> restrictions) {
		StringBuilder sBuilder = new StringBuilder();
		for(Restriction restriction:restrictions) {
			sBuilder.append("&");
			sBuilder.append(restriction.getName());
			sBuilder.append("=");
			sBuilder.append(restriction.getValue());
		}
		return sBuilder.toString();
	}

	public Collection<Auction> search(Search search) throws AuctionXException {
		SimpleXMLParser parser = new SimpleXMLParser();
		String content = getXML(searchUrl + "?as_word=" +  search.getSearch() + this.createQueryString(search.getRestrictions()));
		try {
			Response response = parser.getResponse(content);
			return createAuctions(response);
		} catch (Exception e) {
			throw new AuctionXException(e);
		}
	}

	private Collection<Auction> createAuctions(Response response) {
		Collection<Auction> auctions = new ArrayList<Auction>();
		for(Item item:response.getListing().getItems()) {
			Auction auction = new Auction();
			auction.setCatalogRating(item.getCatalogRating());
			auction.setCondition(item.getCondition());
			auction.setCurrency(item.getCurrency());
			auction.setImageUrl(item.getImageUrl());
			auction.setTitle(item.getTitle());
			auction.setSubtitle(item.getSubtitle());
			auction.setHot("Y".equals(item.getHot()));
			auction.setImageUrl(item.getImageUrl());
			auction.setLink(item.getLink());
			auction.setMercadoPago("Y".equals(item.getMercadoPago()));
			auction.setSellerType(item.getSellerType());
			auction.setType(item.getAuctionType());
			auction.setBids(convertInteger(item.getBids()));
			auction.setHits(convertLong(item.getHits()));
			auction.setPrice(convertDouble(item.getPrice().replace(",", "")));
			auction.setLocation(item.getZones());
			
			Feedback feedback = new Feedback();
			feedback.setComposition(item.getFeedback().getComposition());
			feedback.setPoints(convertLong(item.getFeedback().getPoints().replace("Puntaje: ", "").trim()));
			
			auction.setFeedBack(feedback);
			
			Features features = new Features();
			features.setBold("Y".equals(item.getFeatures().getBold()));
			features.setHighlight("Y".equals(item.getFeatures().getHighlight()));
			features.setPhoto("Y".equals(item.getFeatures().getPhoto()));

			auction.setFeatures(features);
			auctions.add(auction);
		}
		return auctions;
	}

	private Long convertLong(String l) {
		 try {
			 return Long.valueOf(l);
		 } catch ( Throwable t) {}
		 return 0L;
	}

	private Integer convertInteger(String l) {
		 try {
			 return Integer.valueOf(l);
		 } catch ( Throwable t) {}
		 return 0;
	}

	private Double convertDouble(String l) {
		 try {
			 return Double.valueOf(l);
		 } catch ( Throwable t) {}
		 return 0D;
	}

}